#!/usr/bin/perl -w

########################
#                      #
# Modules	       #
#                      #
########################

use strict;  
use CGI;  											#used for collecting parameters from webbrowser
use CGI::Carp qw ( fatalsToBrowser );  								#send fatal errors to webbrowser
use File::Basename;										#used for reading files, not in use.
use XML::Simple;										#used for importing data from maldi
use Data::Dumper;										#used for debugging
use Digest::MD5 qw(md5_hex);
use POSIX;
use DBI;											#loads database modules


########################
#                      #
# Varibles             #
#                      #
########################
		
									    
my %RNA_residuemass = (										#monoisotopic masses for rna oligo mass calculations
		    g => 345.04744,
		    u => 306.02530,
		    c => 305.04129,
		    a => 329.05252,
		  );

my %protein_residuemass = (
			G => 57.02146,								#monoisotopic masses used for calulating peptide masses
			A => 71.03711,
			S => 87.03203,								#FIXED
			P => 97.05276,
			V => 99.06841,
			T => 101.04768,
			C => 103.00919 + 57.02146, 						#103.00919 + 57.02146 carboamidemet modifications
			L => 113.08406,
			I => 113.08406,
			X => 113.08406, # (L or I)
			N => 114.04293,
			O => 114.07931,
			B => 114.53494,# (avg N+D)
			D => 115.02694,
			Q => 128.05858,
			K => 128.09496,
			Z => 128.55059,#(avg Q+E)
			E => 129.04259,
			M => 131.04049,
			H => 137.05891,
			F => 147.06841,
			R => 156.10111,
			Y => 163.06333,
			W => 186.07931
			);

my $mass_of_deuterium = 2.01410178; 								#used to calculte mass difference from linkspacing. 
my $mass_of_hydrogen = 1.00783; 
my $now = localtime time;									#Get time script starts
my $dbh = DBI->connect("dbi:SQLite:dbname=:memory:", "", "",{ RaiseError => 1, AutoCommit => 1 });
												#Use a DB in memory

########################
#                      #
# Import CGI Varibles  #
#                      #
########################

my $query = new CGI;  										#Import CGI POST Data	
  $CGI::POST_MAX = 1024 * 50000;								#Set maxium amount of data that can be sent from web browser
my $protien_sequences  = $query->param('user_protein_sequence');				#Get protien sequences from webpage
my @sequence_names = $protien_sequences =~ m/^>.*$/mg;						#Extract the sequence names from fasta format
  $protien_sequences =~ s/^>.*$/>/mg;								# \
  $protien_sequences =~ s/\n//g;								# | Remove and tidy the sequence names from the input sequences
  $protien_sequences =~ s/^.//;									# |
  $protien_sequences =~ s/ //g;									# /
my $missed_clevages =  $query->param('missed_cleavages');					# load in missed cleavages from webform
my @upload_filehandle; 										# get file-handles (needed for accessing the uploaded file)
  $upload_filehandle[1] = $query->upload("mgf");							#Must be a better way to do this...
  $upload_filehandle[2] = $query->upload("mgf2");
  $upload_filehandle[3] = $query->upload("mgf3");  
  $upload_filehandle[4] = $query->upload("mgf4");  
  $upload_filehandle[5] = $query->upload("mgf5");  
  $upload_filehandle[6] = $query->upload("mgf6");  
  $upload_filehandle[7] = $query->upload("mgf7");  
  $upload_filehandle[8] = $query->upload("mgf8");  
  $upload_filehandle[9] = $query->upload("mgf9");  
  $upload_filehandle[10] = $query->upload("mgf10");  
  $upload_filehandle[11] = $query->upload("mgf11");
  $upload_filehandle[12] = $query->upload("mgf12");
  $upload_filehandle[13] = $query->upload("mgf13");  
  $upload_filehandle[14] = $query->upload("mgf14");  
  $upload_filehandle[15] = $query->upload("mgf15");  
  $upload_filehandle[16] = $query->upload("mgf16");  
  $upload_filehandle[17] = $query->upload("mgf17");  
  $upload_filehandle[18] = $query->upload("mgf18");  
  $upload_filehandle[19] = $query->upload("mgf19");  
  $upload_filehandle[20] = $query->upload("mgf20");
my $reactive_site =  $query->param('reactive_site');						# load in reactive site from webform
my $no_of_fractions = 20;									#how many factions?
my $min_peptide_length = '0';
my $match_ppm = 2;
my $cut_residues;
if ($query->param('enzyme') eq 'Trypsin' )
{
  $cut_residues = 'KR';
} elsif ($query->param('enzyme') eq 'Trypsin/Glu-C')
{
  $cut_residues = 'KRDE';
}
########################
#                      #
# Begin Sub Routines   #
#                      #
########################


sub generate_page												#Main function
{
my $fragment;

create_db();

print_heading  ('MGF Import');
print '<a href="#" onclick="showhide(\'import_mgf\');">Show/hide me</a>';
print "<div class=\'hidden\' id='import_mgf'><table>\n";
print "<tr><td>Fraction</td><td>Scan</td><td>mz</td><td>Charge</td><td>Mass</td><td>Abundance</td><td>MSn Peaks</td></tr>\n";
for (my $n=1; $n <=$no_of_fractions;$n++)
{
  import_mgf($n,$upload_filehandle[$n]);											#Generates a database to load, worth prehaps working around need for DB in future
}
print "</table></div>\n";

print_heading ('Sequence Digests');
print '<a href="#" onclick="showhide(\'digests\');">Show/hide me</a><div class=\'hidden\' id=\'digests\'>';
my @fragments;
my %fragment_source;
my @sequence_fragments;
my @sequences = split '>', $protien_sequences;
my $count = 0;
foreach my $sequence (@sequences)
{
  $count++;
  print_subheading ($sequence_names[$count-1]);
   if ($sequence =~ /[guac]/) {
    @sequence_fragments = digest_rna($missed_clevages, $sequence);
  } else {
    @sequence_fragments = digest_proteins($missed_clevages, $sequence);
  }
  @fragments = (@fragments, @sequence_fragments);
  %fragment_source =  ((map { $_ => $count } @fragments),%fragment_source);
 }
print "</div>";

print_heading ('Fragments Mass');
print '<a href="#" onclick="showhide(\'fragments_masses\');">Show/hide me</a><div class=\'hidden\' id=\'fragments_masses\'>';
my %fragment_masses = digest_proteins_masses(\@fragments,\%protein_residuemass, \%fragment_source);
my %fragment_masses = (%fragment_masses, digest_rna_masses(\@fragments,\%RNA_residuemass));
print "</div>";

print_heading ('Protein Xlink Fragment Masses');
print '<a href="#" onclick="showhide(\'xlink_masses\');">Show/hide me</a><div class=\'hidden\' id=\'xlink_masses\'>';
my ($xlink_fragment_masses_ref,$xlink_fragment_sources_ref) = crosslink_peptides (\%fragment_masses,\%fragment_source);
my %xlink_fragment_masses =  %{$xlink_fragment_masses_ref};
my %xlink_fragment_sources = (%{$xlink_fragment_sources_ref},%fragment_source);
print "</div>";
print_heading ('Peak List');
print '<a href="#" onclick="showhide(\'peak_list\');">Show/hide me</a><div class=\'hidden\' id=\'peak_list\'>';
 my @peaklist =   loadpeaklist_db();
print "</div>";
print_heading ('Peak Matches');

my %fragment_score = matchpeaks(\@peaklist,\%xlink_fragment_masses,\%xlink_fragment_sources);

}

sub import_mgf													#Converts the uploaded MGF into a SQLite database
{
my ($fraction, $file) = @_;				

my %line;
my $MSn_count = 0;
my $dataset = 0;
my $MSn_string;

$line{'fraction'} = $fraction;

while (<$file>) { 

if 	( $_ =~ "BEGIN IONS") 	{   $dataset = $dataset+1;}
elsif 	( $_ =~ "PEPMASS") 	{  
  my $mystring = $_;
  if($mystring =~ m/=(.*?) /) 		{ 	$line{'mz'} = $1;}
  if($mystring =~ m/ (.*?)[\r\n]/) 	{	$line{'abundance'} = $1;}
}
elsif 	( $_ =~ "SCANS")	{  	
    my $mystring = $_;
    if($mystring =~ m/=(.*?)[\r\n]/) 	{    	$line{'scan_num'} = $1;}
}
elsif 	( $_ =~ "CHARGE")	{  	
    my $mystring = $_;
    if($mystring =~ m/=(.*?)\+/) 	{    	$line{'charge'} = $1;}
}
elsif 	( $_ =~ "TITLE")	{  	
    my $mystring = $_;
    if($mystring =~ m/=(.*?)[\r\n]/) 	{    	$line{'title'} = $1;}
}

elsif 	( $_ =~ "^.[0-9]")	{
    $MSn_count= $MSn_count+1;
    $MSn_string = $MSn_string . $_}
elsif 	( $_ =~ "END IONS") 	{ 
  $line{'monoisoptic_mw'} = $line{'mz'} * $line{'charge'} -($line{'charge'}*  1.00728) ;
  print "<tr><td>$line{'fraction'}</td><td>$line{'scan_num'}</td><td>$line{'mz'}</td><td>$line{'charge'}</td><td>$line{'monoisoptic_mw'}</td><td>$line{'abundance'}</td><td>$MSn_count</td></tr>\n";
  my $newline = $dbh->prepare("INSERT INTO msdata (scan_num, fraction, title, charge, mz, abundance, monoisotopic_mw, MSn_string) VALUES (? , ?, ?, ?, ?, ?, ?,?)");
  $newline->execute($line{'scan_num'},$line{'fraction'}, $line{'title'},$line{'charge'},$line{'mz'},$line{'abundance'},$line{'monoisoptic_mw'}, $MSn_string)  ;
  $line{'scan_num'} = $line{'monoisoptic_mw'} = $line{'abundance'} = $MSn_string =  '';
  $MSn_count = 0 ;
  }
}

}

sub matchpeaks													#Matches theoretic digest and crosslink products with doublets found in datas.
{
my ($peaklist_ref, $fragment_masses_ref, $fragment_sources_ref) = @_;
my %fragment_masses = %{$fragment_masses_ref};
my %fragment_sources = %{$fragment_sources_ref};
my @sequences = split ('>',$protien_sequences);
my $max_delta = 1+($match_ppm/1000000); #max delta as ratio

my $score;
my %fragment_score;
my @peaklist = @{$peaklist_ref};
foreach my $fragment (keys %fragment_masses)
{ 
    $fragment_score{$fragment} = 0;
}
my $xlinker;
my $codensation;


my %modifications = (
      MethOx => {
      Name => 'M(ox)',
      Location => 'M',
      Delta => 15.994915,
      },
      MonoLink => {
      Name => 'mono link',
      Location => '[K]',
      Delta => $query->param('mono_mass_diff'),
      },
      #minusH2O => {
      #Name => 'water loss',
      #Location => '^.',
      #Delta => 1.0078250*2  + 15.9949146*1,
      #},
      #borate => {
      #Name => 'Borate',
      #Location => '-',
      #Delta => 25.99639,
      #},
      #Na => {
      #Name => 'Na adduct',
      #Location => '^.',
      #Delta => 22.98922-1.0078250,
      #},
      NoMod => {
      Name => ' ',
      Location => '^.',
      Delta => 0,
      },
#       Carbamyl => {
#       Name => 'Carbamylation',
#       Location => '[^.,C,R,K,M]',
#       Delta => 43.005814,
#       },
      );


print "<table ><tr><td>mass</td><td>sequence</td><td>Mods</td><td>ppm error</td><td>Seq-Seq</td><td>fraction</td><td>xquest</td></tr>";
foreach my $peak (@peaklist)
{
    foreach my $fragment (keys %fragment_masses)
    {   
      
	foreach my $modification (keys %modifications)
	{	  
	    my $location = $modifications{$modification}{Location};
	    my $rxn_residues =  @{[$fragment =~ /$location/g]};
 	    if ($modifications{$modification}{Name} eq "mono link")
 	    {
 	      $rxn_residues = ( $rxn_residues - (2 * @{[$fragment =~ /[-]/g]}));
 	    }
	    for (my $n = 1; $n <= $rxn_residues; $n++)
	    {
	      if (($peak->{monoisotopic_mw}/$peak->{charge} <  (($fragment_masses{$fragment} +($modifications{$modification}{Delta}*$n))/$peak->{charge})*$max_delta)    #Divide by charge to give PPM of detected species otherwise we are 4 times more stick on 4+ m/z
		    && ($peak->{monoisotopic_mw}/$peak->{charge} >  (($fragment_masses{$fragment} +($modifications{$modification}{Delta}*$n))/$peak->{charge})/$max_delta))
	      {
		  $score = (abs(($peak->{monoisotopic_mw} - ($fragment_masses{$fragment}+($modifications{$modification}{Delta}*$n)))))/($fragment_masses{$fragment})*1000000;	
		  print "<tr><td";
		  if ((substr($fragment_sources{$fragment},0,1)-1) != (substr($fragment_sources{$fragment},-1,1)-1))
		  {
		    print " class='green' ";
		  }
		  print ">$peak->{monoisotopic_mw} \t</td><td>",$fragment, "</td><td>";
		  if ($n > 1) { print "$n x ";}
		  print "$modifications{$modification}{Name} </td><td>\t ", "",$score," </td><td>",$fragment_sources{$fragment},"</td><td>",$peak->{'fraction'},"</td>";
# 		  print "<td> RXN$rxn_residues,$location</td>";
		  
		    {
		    print "<td>";		   
		    print_xquest_link($peak->{'MSn_string'},$peak->{'d2_MSn_string'},$peak->{'mz'},$peak->{'charge'},@sequences[(substr($fragment_sources{$fragment},0,1)-1)],@sequences[(substr($fragment_sources{$fragment},-1,1)-1)],$sequence_names[(substr($fragment_sources{$fragment},0,1)-1)],$sequence_names[(substr($fragment_sources{$fragment},-1,1)-1)]);
		    print "</td>";
		    print "<td>";		   
		    print_ms2_link($peak->{'MSn_string'},$peak->{'d2_MSn_string'},$fragment);
		    print "</td>";
		    };
		  print "</tr>\n";
	      }
	    }
	
      }
    }
}
  
print "</table>";
return %fragment_score;
}

sub crosslink_peptides												#Calculates a list of cross-links from a list of peptides
{
# my ($protein_fragments_masses_ref, $fragment_masses_ref) = @_;
# my  %fragment_masses = %{$fragment_masses_ref};
# my %protein_fragment_masses = %{$protein_fragments_masses_ref};
# my $peptide = "1";
my ($peptides_ref, $fragment_source_ref) = @_;
my %peptides = %{$peptides_ref};
my %fragment_source = %{$fragment_source_ref};
my $xlink;
my %xlink_fragment_masses = %peptides;
my %xlink_fragment_sources;


print "<table>\n"; 
foreach my $peptide_1 (sort keys %peptides)
{
  if ($min_peptide_length <= length($peptide_1)) 
  {
    foreach my $peptide_2 (sort keys %peptides)
    { 
     	
	if ($min_peptide_length <= length($peptide_2) && $peptide_1 =~ m/[$reactive_site]/ && $peptide_2 =~ m/[$reactive_site]/ &&   defined $xlink_fragment_masses{$peptide_1.'-'.$peptide_2} == 0 && defined $xlink_fragment_masses{$peptide_2.'-'.$peptide_1} == 0)
 	{
	   print "<tr><td>",$peptides{$peptide_1}+$peptides{$peptide_2}+$query->param('xlinker_mass'),"</td><td>",$peptide_1, "-", $peptide_2, "</td><td>",$fragment_source{$peptide_1}, "-", $fragment_source{$peptide_2}, "</td></tr>\n" ;
	  $xlink = $peptide_1.'-'.$peptide_2;      
	  $xlink_fragment_masses{$xlink} = $peptides{$peptide_1}+$peptides{$peptide_2}+$query->param('xlinker_mass');
	  $xlink_fragment_sources{$xlink} = $fragment_source{$peptide_1}. "-". $fragment_source{$peptide_2};	
      }
    }
  }
}
print "</table>\n";
return (\%xlink_fragment_masses,\%xlink_fragment_sources);
}

sub digest_proteins_masses											#Calculates the mass of a list of peptides
{
my ($protein_fragments_ref, $protein_residuemass_ref,$fragment_source_ref) = @_;
my @protein_fragments = @{$protein_fragments_ref};
my %protein_residuemass = %{$protein_residuemass_ref};
my %fragment_source = %{$fragment_source_ref};
my $peptide_mass = 0;
my $terminalmass=  1.0078250*2  + 15.9949146*1;
my %protein_fragments_masses;

my  @protein_fragments_masses;

print "<table>";

foreach my $peptide (@protein_fragments)
{
  if ($peptide =~ /[ARNDCEQGHILKMFPSTWYV]/)
  {
    my @residues = split //, $peptide;
  
    foreach my $residue (@residues) {									#split the peptide in indivual amino acids
	    $peptide_mass = $peptide_mass + $protein_residuemass{$residue};					#tally the masses of each amino acid one at a time
	  }
    
    print "<tr><td>", $peptide_mass+$terminalmass , "</td><td>",$peptide,"</td><td>",$fragment_source{$peptide},"</td></tr>";
    $protein_fragments_masses{$peptide} = $peptide_mass+$terminalmass;
    $peptide_mass = 0;
  }
}
print "</table>";

return %protein_fragments_masses
}

sub digest_proteins												#Digest a string into an array of peptides
{
my ($missed_clevages, $protein_sequences) = @_;
my  @protein_fragments;
$protein_sequences =~ s/[^A-Z]//g;

print "<p>", $protein_sequences, "</p>\n";
my $protein = $protein_sequences;
    $protein =~ s/[^\w\d>]//g ; 
    my @digest = $protein =~ m/(?:(?:[^$cut_residues]|[$cut_residues]P)*(?:[$cut_residues](?!P)|.(?=$))){1}/g;						#digest peptide into an array of strings using split
    my @single_digest = @digest;
    print "<h3>O Missed</h3><p>", join ("|",@digest), "</p><br>";

    for (my $i=2; $i < $missed_clevages+2; $i++) {
      my @parts = $protein =~ m/(?:(?:[^$cut_residues]|[$cut_residues]P)*(?:[$cut_residues](?!P)|.(?=$))){$i}/g;						#second [KRDE needs to be [KR_EOF_] however you do that

      print "<h3>",  $i-1," Missed</h3><p>",,join ("|",@parts), "</p><br>";
      push(@digest,@parts);

      my @single_digest_trimmed = @single_digest;
      for (my $j=1; $j<$i; $j++) {
	shift @single_digest_trimmed;
	@parts = join("",@single_digest_trimmed) =~ m/(?:(?:[^$cut_residues]|[$cut_residues]P)*(?:[$cut_residues](?!P)|.(?=$))){$i}/g;

	print "<p>",  join ("|",@parts), "</p><br>";
	push(@digest,@parts);  

	}
#       push (@protein_fragments,@digest);
      }
# return @protein_fragments;
return @digest;
}

sub loadpeaklist_db												#Used to load a pregenerated database.
{

my $database = "./crosslinker.sqlitedb";
# my $dbh=DBI->connect("dbi:SQLite:dbname=$database", "", "",{ RaiseError => 1, AutoCommit => 1 });		 #connect to database file

my $masslist=  $dbh->prepare("DROP INDEX IF EXISTS mz_data;");
$masslist->execute();	
$masslist=  $dbh->prepare("CREATE INDEX mz_data ON msdata ( monoisotopic_mw);");
$masslist->execute();	



#Search for peaks within 10% abundance and +11 +/-0.5 Da pair, s2n > 5, scan within 100 scans either side.
my $doublet_ppm_err = $query->param('ms_ppm');;

my $linkspacing = $query->param('seperation');									#number of deuteriums, not mass difference.
my $mass_seperation = $linkspacing * ($mass_of_deuterium-$mass_of_hydrogen);
my $mass_seperation_upper = $mass_seperation * (1+($doublet_ppm_err/1000000));
my $mass_seperation_lower = $mass_seperation * (1-($doublet_ppm_err/1000000));



$masslist = $dbh->prepare("SELECT d1.*, d2.mz as d2_mz, d2.MSn_string as d2_MSn_string,  d2.title as d2_title FROM msdata d1 inner join msdata d2 on (d2.monoisotopic_mw 
                   between d1.monoisotopic_mw + ? and d1.monoisotopic_mw + ? ) and d2.scan_num between d1.scan_num-100 and d1.scan_num +100 and d1.fraction = d2.fraction ");

# and d2.abundance  between d1.abundance * 0.9 and d1.abundance* 1.1
$masslist->execute($mass_seperation_lower,$mass_seperation_upper);	

my $isopairs;
my @peaklist;

print "<table ><tr><td>fraction</td><td>scan_num,</td><td>\tmonoisotopic_mw,</td><td>\tmz,</td><td>charge</td><td>heavy mz</td><td>\tabundance\n</td></tr>";

while (my $searchmass = $masslist->fetchrow_hashref) {
  my $button = '';
  print ("<tr><td>$searchmass->{'fraction'}\t</td><td>$searchmass->{'scan_num'}\t</td><td>$searchmass->{'monoisotopic_mw'}</td><td>\t$searchmass->{'mz'}</td><td>\t$searchmass->{'charge'}</td><td>\t$searchmass->{'d2_mz'}</td><td>\t$searchmass->{'abundance'}\n</td><td>");
  print_xquest_link($searchmass->{'MSn_string'},$searchmass->{'d2_MSn_string'},$searchmass->{'mz'},$searchmass->{'charge'}, $query->param('user_protein_sequence'));
  print "</td></tr>";
  push(@peaklist,$searchmass)
  
}											#pull all records from our database of scans.

print ("</table><br/><br/>");

return @peaklist;


}

sub digest_rna_masses												#Not in use
{
my %fragment_masses;

my ($fragments_ref, $RNA_residuemass_ref) = @_;
my @fragments = @{$fragments_ref};
my %RNA_residuemass = %{$RNA_residuemass_ref};
my $terminalmass=  1.0078250*2  + 15.9949146*1;

print "<table >";
foreach my $fragment (@fragments){ 
  if ($fragment =~ /[guca]/)
  {
    foreach my $residue (split //, $fragment) {										#split the peptide in indivual amino acids
    $fragment_masses{$fragment} =  $fragment_masses{$fragment} + $RNA_residuemass{$residue};							#tally the masses of each amino acid one at a time
    }
    $fragment_masses{$fragment} = $fragment_masses{$fragment}+$terminalmass;
    print "<tr><td>$fragment</td><td>$fragment_masses{$fragment}</td></tr>";
  }

}
print "</table>";

return (%fragment_masses); #, \%rna_fragment_masses_duplicity);
}

sub digest_rna													#Not in use
{
my ($missed_clevages, $RNA_sequence) = @_;
# print $RNA_sequence ,"\n";
$RNA_sequence =~ s/[^gctua]//g;


    my @fragments = $RNA_sequence =~ m/(?:[^g]*(?:g|.(?=$))){1}/g;						#digest peptide into an array of strings using split
    my @single_digest = @fragments;
    print "O Missed\n", join ("|",@fragments), "\n\n";
    for (my $i=2; $i < $missed_clevages+2; $i++) {
      my @parts = $RNA_sequence =~ m/(?:[^g]*(?:g|.(?=$))){$i}/g;						#second [KRDE] needs to be [KR_EOF_] however you do that
     print  $i-1," Missed\n",,join ("|",@parts), "\n\n";
      push(@fragments,@parts);
      my @single_digest_trimmed = @single_digest;
      for (my $j=1; $j<$i; $j++) {
	shift @single_digest_trimmed;
	@parts = join("",@single_digest_trimmed) =~ m/(?:[^g]*(?:g|.(?=$))){$i}/g;
	print  join ("|",@parts), "\n\n";
	push(@fragments,@parts);  
	}
    }
return @fragments;

}

sub loadpeaklist_xml												#Not in use
{
my $xml = new XML::Simple (KeyAttr=>[]);
# read XML file
my $data = $xml->XMLin("peaklist.xml");


	foreach my $peak (@{$data->{pk}})
		{
			print $peak->{mass}, "\n";# "\t", my $cc->{area}, "\n";	
		}

return $data;
}

########################
#                      #
# HTML Output	       #
#                      #
########################


sub print_xquest_link 												#Creates Link to Xlink
{

my $linkspacing = $query->param('seperation');									#number of deuteriums, not mass difference.
my $mass_seperation = $linkspacing * ($mass_of_deuterium-$mass_of_hydrogen);

my ($MSn_string, $d2_MSn_string,$mz,$charge,$sequence1,$sequence2, $sequence1_name, $sequence2_name) = @_;
print  '
<form method="post" target="_blank"  action="http://prottools.ethz.ch/orinner/public/cgi-bin/xquest/xquest.cgi" enctype="multipart/form-data">
<input type="hidden" name="usepastedata" value="1"/>
<input type="hidden" name="define_enzyme" value="c@',$cut_residues,'^P" size="10" maxlength="10" />
<input type="hidden" name="xlinkermw" value="',$query->param('xlinker_mass'),'" size="10" maxlength="15" />
<input type="hidden" name="monolinkmw" value="',$query->param('xlinker_mass')+ $query->param('mono_mass_diff'),'" size="30" maxlength="60" />
<input type="hidden" name="cp_isotopediff", value="', $mass_seperation,'" size="8" maxlength="10" />
<input type="hidden" name="ionisation"  value="ESI">
<input type="hidden" name="AArequired" value="',$query->param('reactive_site'),'" size="10" maxlength="10" />
<input type="hidden" name="AAshift" value="C:57.02146" size="20" maxlength="20" />
<input type="hidden" name="ms1tolerance" value="10" size="3" maxlength="10" align="left" />
<input type="hidden" name="tolerancemeasure" value="ppm"  />
<input type="hidden" name="ms2tolerance" value="0.5" size="5" maxlength="10" />
<input type="hidden" name="advanced" value="on" />
<input type="hidden" name="dataupload" value="paste text data"  />
<input type="hidden" name="mindigestlength" value="3" size="2" maxlength="3" />
<input type="hidden" name="maxdigestlength" value="40" size="2" maxlength="3" />
<input type="hidden" name="missed_cleavages" value="2" size="2" maxlength="3" /> 
<input type="hidden" name="cutatxlink" value="on" default="1" />
<input type="hidden" name="variable_mod" value="M:15.99" size="20" maxlength="20" />
<input type="hidden" name="xlink_ms2tolerance" value="0.5" size="2" maxlength="10" /> 
<input type="hidden" name="minionsize" value="200" size="2" maxlength="10" />
<input type="hidden" name="maxionsize" value="1600" size="2" maxlength="10" />
<input type="hidden" name="ionseries_b" value="1" />
<input type="hidden" name="ionseries_y" value="1"  />
<input type="hidden" name="cp_threshold" value="1" size="2" maxlength="3" /> 
<input type="hidden" name="cp_dynamic_range" value="1000" size="2" maxlength="4" />
<input type="hidden" name="precursor_mz" value="',$mz,'" size="10" maxlength="15" />
<input type="hidden" name="precursor_charge" value="',$charge,'" size="10" maxlength="1" label="precursor charge   " />
<input type="hidden" name="pastedatabase" value="';

if (defined $sequence2 == 0 ||defined $sequence1_name == 0) {
print $sequence1;
}
elsif (defined $sequence2 == 0 || $sequence1 eq $sequence2) {
print $sequence1_name,$sequence1;
} else {
print $sequence1_name,$sequence1,'

', $sequence2_name,$sequence2;
}
print '">

<input type="hidden" name="pastedta1"  value="',$MSn_string,'">
<input type="hidden" name="pastedta2"  value="',$d2_MSn_string,'">
<input type="hidden" name=".cgifields" value="dataupload"  /><input type="hidden" name=".cgifields" value="ionseries_a"  /><input type="hidden" name=".cgifields" value="tolerancemeasure"  /><input type="hidden" name=".cgifields" value="decoy"  />
<input type="hidden" name=".cgifields" value="Iontagmode"  /><input type="hidden" name=".cgifields" value="ionseries_c"  /><input type="hidden" name=".cgifields" value="advanced"  /><input type="hidden" name=".cgifields" value="cutatxlink"  /><input type="hidden" name=".cgifields" value="ionseries_b"  /><input type="hidden" name=".cgifields" value="ionseries_z"  /><input type="hidden" name=".cgifields" value="ionseries_x"  /><input type="hidden" name=".cgifields" value="ionseries_y"  />
<input type="submit" name="update" value="xQuest" />
</form>
';

}

sub create_db
{
my $masslist=  $dbh->prepare("DROP TABLE IF EXISTS msdata;");
$masslist->execute();
$dbh->do("CREATE TABLE msdata (scan_num number,fraction, title, charge number, mz number, monoisotopic_mw number, abundance number, MSn_string) ");

}
sub print_ms2_link 												#Creates Link to Xlink
{

my ($MSn_string,$d2_MSn_string, $sequence) = @_;
print  '
<form method="post" target="_blank"  action="flot/ms2.pl" enctype="multipart/form-data">
<input type="hidden" name="data" value="',$MSn_string,'"  />
<input type="hidden" name="data2"  value="',$d2_MSn_string,'">
<input type="hidden" name="sequence" value="',$sequence,'" />
<input type="hidden" name="xlinkermw" value="',$query->param('xlinker_mass'),'" size="10" maxlength="15" />
<input type="submit" name="update" value="ms2" />
</form>
';

}

sub print_heading												#Prints HTML heading
{
print "<br><br><h1>@_</h1><hr><br>"
}

sub print_subheading												#Prints HTML subheading
{
print "<h2>@_</h2>"
}



########################
#                      #
# Main Program         #
#                      #
########################

# 
 print "Content-type: text/html\n\n";
# print "<html>\n<head><title>Crosslinker</title></head>\n<body>\n";
# print "Crosslinker output: $now\n";


print <<ENDHTML;
<html>
<head>
  <title>MS-Crosslink</title>
<script language="javascript">
<!--

var state = 'none';

function showhide(layer_ref) {

if (state == 'block') {
state = 'none';
}
else {
state = 'block';
}
if (document.all) { //IS IE 4 or 5 (or 6 beta)
eval( "document.all." + layer_ref + ".style.display = state");
}
if (document.layers) { //IS NETSCAPE 4 or below
document.layers[layer_ref].display = state;
}
if (document.getElementById &&!document.all) {
hza = document.getElementById(layer_ref);
hza.style.display = state;
}
}
//-->
</script> 
  <style type="text/css">
body {
	background: #c7c2bc; 
	background-repeat: repeat-y;
 	background-position: center;
	font-family: Arial, Helvetica, sans-serif;
	width: 1012px;
    margin-left:auto;
    margin-right:auto;
	

}
#shadow-container {
	 background:white;
}
 

div {
  padding: 0px;
}
   div.tail {
     background: black;
     width: 992px;
     height: 2px;
     
     margin:10px;
    }
   div.title {
     background: white;
     width: 950px;
     height: 122px;
     text-align:center;
     margin: auto;
     
    }
   div.white {
     background-color: white;
     width: 950px;
     text-align:left;
     margin: auto;
    
     }
   div.black {
     background: black;
     height: 2px;
     width: 992px;
     text-align:left;
    margin:10px;
    }
    h1 {
    color:  #00505c;
    margin: 0;
    }
div.hidden {
   display: none;
   }
p {
    word-wrap: break-word;
  }
table {
	margin:auto;
	width:80%;
	text-align: center;
}
.green
{
    background-color: #50F0Fc;
}
td
{
    border-color: #600;
    text-align: left;
    margin: 0;
    padding: 10px;   
    background-color:  #d0d0d0;
}
td.half
{
  width:50%;
}

  </style>

</head>
<body>
<div id="shadow-container">
	

<div class="title">
<br/><br/><h1>Crosslinker</h1>
</div>
<div class="black">
</div>
<div class="white">
<br/><br/>

ENDHTML

generate_page;

print '<br/><br/>
</div>
</div>
 


</body>
</html>';
exit;

